// Copyright 2007-2008 Rory Plaire (codekaizen@gmail.com)

using System;

namespace NPack.Interfaces
{
    /// <summary>
    /// An interface to an affine transformation matrix.
    /// </summary>
    /// <typeparam name="T">Type of element in the matrix.</typeparam>
    public interface IAffineTransformMatrix<T> : ITransformMatrix<T>
        where T : IEquatable<T>, IComparable<T>, IComputable<T>, IConvertible
    {
        /// <summary>
        /// Gets the inverse of the affine transform.
        /// </summary>
        new IAffineTransformMatrix<T> Inverse { get; }

        /// <summary>
        /// Resets the affine transform to the identity matrix (a diagonal of one).
        /// </summary>
        void Reset();

        /// <summary>
        /// Rotates the affine transform around the given <paramref name="axis"/> 
        /// at the given <paramref name="point"/>.
        /// </summary>
        /// <param name="point">Point at which to compute the rotation.</param>
        /// <param name="axis">The axis to rotate around.</param>
        /// <param name="radians">Angle to rotate through.</param>
        void RotateAt(IVector<T> point, IVector<T> axis, Double radians);

        /// <summary>
        /// Rotates the affine transform around the given <paramref name="axis"/> 
        /// at the given <paramref name="point"/>.
        /// </summary>
        /// <param name="point">Point at which to compute the rotation.</param>
        /// <param name="axis">The axis to rotate around.</param>
        /// <param name="radians">Angle to rotate through.</param>
        /// <param name="order">Order in which to apply the operation.</param>
        void RotateAt(IVector<T> point, IVector<T> axis, Double radians, MatrixOperationOrder order);

        /// <summary>
        /// Translates the affine transform by the given amount in each dimension.
        /// </summary>
        /// <param name="amount">Amount to translate by.</param>
        void Translate(T amount);

        /// <summary>
        /// Translates the affine transform by the given amount in each dimension.
        /// </summary>
        /// <param name="amount">Amount to translate by.</param>
        /// <param name="order">Order in which to apply the operation.</param>
        void Translate(T amount, MatrixOperationOrder order);

        /// <summary>
        /// Translates the affine transform by the given translation vector.
        /// </summary>
        /// <param name="translateVector">
        /// A vector whose components will translate the transform 
        /// in the corresponding dimension.
        /// </param>
        void Translate(IVector<T> translateVector);

        /// <summary>
        /// Translates the affine transform by the given translation vector.
        /// </summary>
        /// <param name="translateVector">
        /// A vector whose components will translate the transform 
        /// in the corresponding dimension.
        /// </param>
        /// <param name="order">Order in which to apply the operation.</param>
        void Translate(IVector<T> translateVector, MatrixOperationOrder order);


    }
}